let Mongodb = require('../../database/mongodb');
let exceljs = require('../../utils/exceljs')

class CommonImportService {
  constructor () {
    this.dataCache = []
  }

  importData (params) {
    return new Promise((resolve, reject) => {
      initFormateData.call(this, params).then(() => {
        return exceljs.getData(params.filePath)
      }).then((data) => {
        return this.formateData.call(this, data, params)
      }).then((data) => {
        this.saveData(params.config, data, params.isCover)
        resolve()
      }).catch((err) => {
        reject(err)
      })
    })
  }
  
  // 格式化数据
  dataFormater (key, value, idName = 'id', valueName = 'name') {
    if (value && this.dataCache[key] && this.dataCache[key].length > 0) {      
      let data = this.dataCache[key].find(item => {        
        return item[valueName] === value
      })
      if (data) {
        return data[idName]
      } else {
        return ''
      }
    } else {
      return ''
    }
  }

  /**
   * 用户列表数据转换转换
   * @param {*} dataList 
   * @param {*} valueArr 
   * @param {*} key 
   */
  dataArrFormatter (key, values, idName = 'id', valueName = 'name') {
    if (values && this.dataCache[key] && this.dataCache[key].length > 0) {      
      let result = []
      this.dataCache[key].forEach(item => {
        if (values.indexOf(item[valueName]) != -1) {
          result.push(item[idName])
        }
      })
      return result
    } else {
      return []
    }
  }

  formateData (dataList, params) {
    console.log(dataList)
    return new Promise((resolve, reject) => {
      let rowDatas = []
      let data = {}
      for (let i = 0, len = dataList.length; i < len; i++) {
        data = dataList[i]
        let row = {};
        let ext = {};
        let colIndex = 0;
        let colValue;
        params.config.header.forEach((col, index) => {
          ext = col.ext;
          colIndex = index;
          colValue = data[colIndex];
          if (ext.type === "default") {
            row[ext.prop] = colValue;
          } else if (ext.type === "enum") {
            if (ext.mutil) {
              row[ext.prop] = this.dataArrFormatter(ext.key, colValue, ext.value || "value", ext.label || "name");
            } else {
              row[ext.prop] = this.dataFormater(ext.key, colValue, ext.value || "value", ext.label || "name");
            }
          } else if (ext.type === "table") {
            if (ext.mutil) {
              row[ext.prop] = this.dataArrFormatter(ext.key, colValue, ext.value || "_id", ext.label || "name");
            } else {
              row[ext.prop] = this.dataFormater(ext.key, colValue, ext.value || "_id", ext.label || "name");
            }
          } else if (ext.type === "date") {
            row[ext.prop] = colValue
          } else if (ext.type === "date_year") {
            row[ext.prop] = colValue
          } else if (ext.type === "custom") {
            row[ext.prop] = this[ext.func](data)
          }
        })
        rowDatas.push(row)
      }
      console.log(rowDatas)
      resolve(rowDatas)
    })
  }

  // 默认新增，子类可以覆盖该方法进行覆盖新增处理
  saveData (config, items, isCover) {
    return new Promise((resolve, reject) => {
      if (items && items.length > 0) {
        if (config.keyPropName) {
          let proName = config.keyPropName;
          items.forEach(item => {
            let condition = {
              [proName]: item[proName]
            }
            Mongodb.count(config.tableName, condition, (err, count) => {
              if (count > 0) {
                console.log("item:已有")
                if (isCover) {
                  console.log("item:更新")
                  Mongodb.update(config.tableName, condition, item);
                }
              } else {
                console.log("item:保存")
                console.log(item)
                Mongodb.save(config.tableName, item);
              }
            })
          })
        } else {
          Mongodb.saveDocs(config.tableName, items, (err, docs) => {
            if (err) {
              reject(err);
            } else {
              resolve(docs);
            }
          })
        }
        
        resolve()
      } else {
        resolve()
      }
    });
  }
}

// 私有方法
function saveData (tableName, docs) {
  return new Promise((resolve, reject) => {
    Mongodb.saveDocs(tableName, docs, (err, docs) => {
      if (err) {
        reject(err);
      } else {
        resolve(docs);
      }
    });
  });
}

function getTableData (config) {
  return new Promise((resolve, reject) => {
    Mongodb.find(config.tableName, config.condition || {}, config.fields || {}, {}, (err, docs) => {
      if (err) {
        reject(err);
      } else {
        this.dataCache[config.tableName] = docs
        resolve();
      }
    });
  });
}

function getEnum (enumTypeKey) {
  return new Promise((resolve, reject) => {
    Mongodb.find('param_exts', {csName: enumTypeKey}, {}, {}, (err, docs) => {
      if (err) {
        reject(err);
      } else {
        this.dataCache[enumTypeKey] = docs
        resolve();
      }
    });
  });
}

function initFormateData (params) {
  return new Promise((resolve, reject) => {
    const enumPromise = params.config.enumTypes.map((key) => {
      return getEnum.call(this, key);
    });
    const baseInfoPromise = params.config.tableConfigs.map((config) => {
      return getTableData.call(this, config)
    })
    Promise.all(enumPromise.concat(baseInfoPromise)).then((data) => {
      resolve()
    }).catch((err) => {
      reject(err)
    })
  })
}

module.exports = new CommonImportService()
